import { defineStore } from 'pinia'
import api from '@/utils/api'
import webSocketService from '@/utils/webSocket'
import { useAuthStore } from './auth'

export const useNotificationStore = defineStore('notifications', {
  state: () => ({
    notifications: [],
    isLoading: false,
    hasMore: true,
    unreadCount: 0,
    subscribedChannels: new Set()
  }),
  actions: {
    initWebSocket() {
      const authStore = useAuthStore()
      if (!authStore.user?.id) return
      const channel = `/user/${authStore.user.id}/notifications`
      if (this.subscribedChannels.has(channel) || !webSocketService.isConnected) {
        return
      }
      webSocketService.subscribe(
        channel,
        (message) => {
          try {
            const notification = JSON.parse(message.body)
            this.addNotification(notification)
          } catch (error) {
            console.error('解析WebSocket通知失败:', error)
          }
        },
        (error) => {
          console.error(`WebSocket订阅频道[${channel}]失败:', error`)
          this.subscribedChannels.delete(channel)
        }
      )
      this.subscribedChannels.add(channel)
    },
    unsubscribeWebSocket(channel) {
      if (this.subscribedChannels.has(channel)) {
        webSocketService.unsubscribe(channel)
        this.subscribedChannels.delete(channel)
      }
    },
    addNotification(newNotification) {
      const isDuplicate = this.notifications.some(n => n.id === newNotification.id)
      if (isDuplicate) return
      this.notifications.unshift(newNotification)
      if (!newNotification.read) {
        this.unreadCount++
      }
    },
    async fetchNotifications(forceRefresh = false) {
      if (this.isLoading) return
      const authStore = useAuthStore()
      const userId = authStore.user?.id
      if (!userId) return
      this.isLoading = true
      try {
        const page = forceRefresh ? 1 : Math.ceil(this.notifications.length / 20)
        const response = await api.get(`/api/notifications/user/${userId}`, {
          params: { page, pageSize: 20 }
        })
        const newNotifications = response.data || []
        if (forceRefresh) {
          this.notifications = newNotifications
          this.unreadCount = newNotifications.filter(n => !n.read).length
        } else {
          this.notifications.push(...newNotifications)
        }
        this.hasMore = newNotifications.length >= 20
      } catch (error) {
        console.error('加载通知欋列表失败:', error)
        this.hasMore = false
      } finally {
        this.isLoading = false
      }
    },
    async fetchUnreadNotifications() {
      if (this.isLoading) return
      const authStore = useAuthStore()
      const userId = authStore.user?.id
      if (!userId) return
      this.isLoading = true
      try {
        const response = await api.get(`/api/notifications/user/${userId}/unread`)
        const unreadNotifications = response.data || []
        this.notifications = unreadNotifications
        this.unreadCount = unreadNotifications.length
        this.hasMore = false
      } catch (error) {
        console.error('加载未读通知失败:', error)
      } finally {
        this.isLoading = false
      }
    },
    async markAsRead(notificationId) {
      const authStore = useAuthStore()
      if (!authStore.user?.id || !notificationId) return
      try {
        await api.patch(`/api/notifications/${notificationId}/read`)
        const index = this.notifications.findIndex(n => n.id === notificationId)
        if (index !== -1 && !this.notifications[index].read) {
          this.notifications[index].read = true
          this.unreadCount = Math.max(0, this.unreadCount - 1)
        }
      } catch (error) {
        console.error(`标记通知[${notificationId}]已读失败:`, error)
        throw error
      }
    },
    async markAllAsRead() {
      const authStore = useAuthStore()
      const userId = authStore.user?.id
      if (!userId || this.unreadCount === 0) return
      try {
        await api.patch(`/api/notifications/user/${userId}/read-all`)
        this.notifications.forEach(notification => {
          if (!notification.read) {
            notification.read = true
          }
        })
        this.unreadCount = 0
      } catch (error) {
        console.error('全部标记通知已读失败:', error)
        throw error
      }
    }
  }
})